import os.path
from cinrad.io import CinradReader, StandardData
import cinrad
import datetime
from utils.Logger import get_logger
from multiprocessing import Process, Queue

logger = get_logger()
# 每一层对应的仰角产品
# TREF:（Total Reflectivify）
#
# REF: 反射率因子（Reflectivity）
# 反映雷达信号被气象目标（如雨滴、雪花等）反射的强度，通常用于判断降水强度。
#
# VEL: 径向速度（Velocity）
# 指向雷达天线的方向上，传播气象目标（如风）相对于雷达的移动速度，用于风场分析。
#
# SW: 速度宽度（Spectrum Width）
# 反映风速的变化范围，通常用于分析风的湍流程度和混合状态。
#
# ZDR: 差分反射率（Differential Reflectivity）
# 衡量水平和垂直极化反射率的比例，用于区分雨滴形状和尺寸，以及辨别不同类型的降水（如雨、雪等）。
#
# RHO: 相关系数（Correlation Coefficient）
# 表示回波信号的相关性，通常用来分析降水粒子的分布及其均匀性。
#
# PHI: 相位差（Differential Phase）
# 描述不同极化信号之间的相位差，对于降水粒子形态和类型的分析非常有用。
#
# KDP: 差分相位（Differential Phase Shift）
# 表示降水过程中信号的相位变化，主要用于估算降水强度和识别特定气象现象。
#
# SNRH: 水平极化信号的信噪比（Signal-to-Noise Ratio for Horizontal Polarization）
# 衡量接收雷达信号的强度与背景噪声的比率，影响数据的质量和可靠性。
# ['TREF', 'REF', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# ['TREF', 'REF', 'VEL', 'SW', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
# 仰角列表
angle_list = [0.48339844, 0.48339844, 1.4941406, 1.4941406, 2.4169922, 3.3398438, 4.3066406, 5.229492, 6.196289, 7.5146484, 8.701172,
              10.019531, 11.99707, 14.018555, 16.699219, 19.511719]
# 包含数据的仰角列表  去除重复项
angle_index = [0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
# 暂时不支持SNRH 和SW
# TREF暂时不绘制
# ZDR、RHO、REF、KDP是为了绘制HCL防止重复调用
exclude_list = ["SNRH", "SW", "TREF", "PHI", "VEL"]


def getProducts(path, parent_dir, currentTime):
    logger.info("开始绘制" + currentTime + "的二次产品")
    f = StandardData(path)
    f.scantime = f.scantime + datetime.timedelta(hours=8)  # 修改为北京时间
    filterData = list(f.iter_tilt(230, 'REF'))

    # 创建进程列表
    processes = []

    # 绘制VIL
    vil_process = Process(target=getVIL, args=(filterData, parent_dir, currentTime + ".png"))
    vil_process.start()
    processes.append(vil_process)

    # 绘制ET
    et_process = Process(target=getET, args=(filterData, parent_dir, currentTime + ".png"))
    et_process.start()
    processes.append(et_process)

    # 绘制CR
    cr_process = Process(target=getCR, args=(filterData, parent_dir, currentTime + ".png"))
    cr_process.start()
    processes.append(cr_process)

    # 绘制HCL
    hcl_process = Process(target=getHCL, args=(path, currentTime + ".png", parent_dir))  # 只传递必要参数
    hcl_process.start()
    processes.append(hcl_process)

    # 处理每个仰角的产品
    for i, index in enumerate(angle_index):
        product_info = f.available_product(index)
        for product in product_info:
            if product in exclude_list:  # 不绘制的产品
                continue
            # 重新在进程内获取数据
            data = f.get_data(index, 230, product)

            # 创建绘图进程
            product_process = Process(target=draw_product, args=(data, parent_dir, product, i + 1, currentTime))
            product_process.start()
            processes.append(product_process)

    # 等待所有进程完成
    for p in processes:
        p.join()


def draw_product(data, parent_dir, product, index, currentTime):
    productName = os.path.join(parent_dir, product)
    if not os.path.exists(productName):
        os.mkdir(productName)

    # 对应仰角层级所在的文件夹
    product_index_name = os.path.join(productName, str(index))
    if not os.path.exists(product_index_name):
        os.mkdir(product_index_name)

    fig = cinrad.visualize.PPI(data, dpi=300, style="white", add_city_names=True)
    fig(os.path.join(product_index_name, currentTime + ".png"))


# 计算VIL 垂直液态水
def getVIL(data, parent_dir, filename):
    parent_dir = os.path.join(parent_dir, "VIL")
    if not os.path.exists(parent_dir):
        os.mkdir(parent_dir)
    filename = os.path.join(parent_dir, filename)
    vil = cinrad.calc.quick_vil(data)
    fig = cinrad.visualize.PPI(vil, dpi=300, style="white", add_city_names=True)
    fig(filename)  # 保存图片


# 绘制ET 回波顶高
def getET(data, parent_dir, filename):
    parent_dir = os.path.join(parent_dir, "ET")
    if not os.path.exists(parent_dir):
        os.mkdir(parent_dir)
    filename = os.path.join(parent_dir, filename)
    et = cinrad.calc.quick_et(data)
    fig = cinrad.visualize.PPI(et, dpi=300, style="white", add_city_names=True)
    fig(filename)


# 绘制CR Compose Reflectivity 组合反射率
def getCR(data, parent_dir, filename):
    parent_dir = os.path.join(parent_dir, "CR")
    if not os.path.exists(parent_dir):
        os.mkdir(parent_dir)
    filename = os.path.join(parent_dir, filename)
    # 在这里重新处理数据, 确保传递的是简单数据类型
    cr = cinrad.calc.quick_cr(data)
    fig = cinrad.visualize.PPI(cr, dpi=300, style="white", add_city_names=True)
    fig(filename)


# 计算水凝物分类 该计算需要依赖于多个结果包括ref zdr rho kdp
def getHCL(path, currentTime, parent_dir):
    f = StandardData(path)
    ref = f.get_data(0, 230, "REF")
    zdr = f.get_data(0, 230, "ZDR")
    rho = f.get_data(0, 230, "RHO")
    kdp = f.get_data(0, 230, "KDP")
    # 计算混合分类
    cHCL = cinrad.calc.hydro_class(ref, zdr, rho, kdp, band="S")  # band手动输入S/C/X
    # 生成混合分类图像
    path = os.path.join(parent_dir, "HCL")
    if not os.path.exists(path):
        os.mkdir(path)
    filename = os.path.join(path, currentTime)
    fig = cinrad.visualize.PPI(cHCL, add_city_names=True, dpi=300, style="white")
    fig(filename)


if __name__ == '__main__':
    path = "../binData/Z_RADR_I_Z9311_20240604233600_O_DOR_SAD_CAP_FMT.bin.bz2"
    getProducts(path, "../binData", "20240604233600")
    # f = cinrad.io.read_auto(path)
    # print(f.el)
    # print(f.available_tilt("REF"))
    #
    # print(f.available_tilt("TREF"))
    # print(f.available_tilt("ZDR"))
    #
    # ref = f.get_data(0, 230, "REF")  # 这里全部使用的是第一个仰角的
    # zdr = f.get_data(0, 230, "ZDR")
    # rho = f.get_data(0, 230, "RHO")
    # kdp = f.get_data(0, 230, "KDP")
    # cHCL = cinrad.calc.hydro_class(ref, zdr, rho, kdp, band="S")  # band手动输入S/C/X
    # fig = cinrad.visualize.PPI(cHCL, add_city_names=True, dpi=300, style="black")
    # fig("test.png")
